package com.example.demo.service.impl;

import com.alibaba.druid.pool.DruidDataSource;
import com.example.demo.dao.BmDatasourceManagementMapper;
import com.example.demo.datasource.DataSourceManager;
import com.example.demo.entity.BmDatasourceManagement;
import com.example.demo.entity.SqlInfo;
import com.example.demo.enums.CommonCodeEnum;
import com.example.demo.response.Request;
import com.example.demo.service.BmDatasourceManagementService;
import com.example.demo.utils.CommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 数据源管理表(BmDatasourceManagement)表服务实现类.
 *
 * @author suliwei
 * @since 2025/5/26 15:00
 */
@Slf4j
@Service("bmDatasourceManagementService")
public class BmDatasourceManagementServiceImpl implements BmDatasourceManagementService {
    @Resource
    private BmDatasourceManagementMapper bmDatasourceManagementMapper;

    @Resource
    private DataSourceManager dataSourceManager;

	/**
	 * 根据sql查询数据
	 *
	 * @param sqlInfo
	 * @return
	 */
	@Override
	public Request getDataBySql(SqlInfo sqlInfo) {
		if (null == sqlInfo.getCallSql()){
			return Request.response(0001, "sql语句为空!");
		}
		Map<String, String> inputParam = getInputParam(sqlInfo.getInputParams());
		String sql = getSql(sqlInfo.getCallSql(), inputParam);
		/*
		if (sql.contains("${")){ //如果替换后的sql还含有变量时，直接返回
			log.error(ResultStatusEnum.SQL_IS_ERROR.getMessage());
			return ApiResponse.response(ResultStatusEnum.SQL_IS_ERROR.getStatus(),ResultStatusEnum.SQL_IS_ERROR.getMessage());
		}
		*/
		BmDatasourceManagement datasourceManagement = new BmDatasourceManagement();
		if (null != sqlInfo.getDataSourceId()){
			if(CommonCodeEnum.DEFAULT_DATA_SOURCE.getCode().equals(sqlInfo.getDataSourceId())){
				datasourceManagement.setDatasourceId(sqlInfo.getDataSourceId());
			}else {
				datasourceManagement = this.bmDatasourceManagementMapper.selectByPrimaryKey(sqlInfo.getDataSourceId());
			}
		}else {
			datasourceManagement = null;
		}

		DruidDataSource dataSourcePool = dataSourceManager.getDataSourcePool(datasourceManagement);
		Connection connection = null;
		PreparedStatement ps = null;
		List<Map<String, Object>> resultList = new ArrayList<>();
		try {

			connection = dataSourcePool.getConnection();
			ps = connection.prepareStatement(sql);
			ResultSet resultSet = ps.executeQuery();
			while (resultSet.next()) {
				Map<String, Object> row = new HashMap<>();
				ResultSetMetaData metaData = resultSet.getMetaData();
				int columnCount = metaData.getColumnCount();

				for (int i = 1; i <= columnCount; i++) {
					String columnName = metaData.getColumnName(i);
					Object value = resultSet.getObject(i);
					row.put(columnName, value);
				}
				resultList.add(row);
			}
		}catch (Exception e){
			log.error("执行sql异常：{}",e);
			return Request.response(9999,";运行sql:"+sql+"异常!");
		}finally {
			dataSourceManager.closeConnection(connection, ps);
		}
		return Request.success(resultList);
	}

	private String getSql(String callSql,Map<String, String> paramsMap){

		Pattern NUMBER_PATTERN = Pattern.compile("\\$.*?}");
		//预处理输出数据sql
		String sqlTable = callSql.replace("\n", " ").replace("\t", " ");
		String[] str = sqlTable.replace(",", " ").split(" ");
		log.info("sqlTable========{}",sqlTable);
		log.info("##############  处理sql模板开始");
		long t1 = System.currentTimeMillis();
		for (int i = 0; i < str.length; i++) {
			////解析sql，得到sql语句：
			if (str[i].contains("$")) {
				Matcher matcher = NUMBER_PATTERN.matcher(str[i]);
				if (matcher.find()) {
					String match = matcher.group();
					if (Objects.isNull(paramsMap) || Objects.isNull(paramsMap.get(match))){
						sqlTable = sqlTable.replace(match, CommonUtil.getCommonParamValue(match).toString());
					}else {
						sqlTable = sqlTable.replace(match, CommonUtil.getCommonParamValue(paramsMap.get(match)).toString());
					}
				}
			}
		}
		long t2 = System.currentTimeMillis();
		log.info("############## 处理sql模板完成，耗时：" + (t2 - t1) / 1000.0 + "s");
		log.info("生成的sql========> {}",sqlTable);
		return sqlTable;
	}

	private Map<String,String> getInputParam(String inputParams){

		if (null == inputParams){
			return null;
		}

		// 暂存key
		String match = "";
		// 奇偶标志
		int flag = 1;
		//正则切割
		String[] arrays = inputParams.replaceAll(" ","").split("\\$\\{|\\}\\=");
		Map<String, String> model = new HashMap<>();

		for (String str : arrays) {
			// 空值跳过
			if ("".equals(str)) {
				continue;
			}
			//去除空格
			String replace = str.replace(" ", "");
			//去除中文逗号
			replace = replace.replace("，","");
//            System.out.println("replace==="+replace);
			//末位判断
			String substring = replace.substring(replace.length() - 1);
			if (",".equals(substring)) {
				//去除末位
				replace = replace.substring(0, replace.length() - 1);
			}

			// key-value逻辑处理
			if (flag % 2 != 0) {
				// key
				replace = "${" + replace + "}";
				match = replace;
			} else {
				//value
				model.put(match, replace);
				// 替换完成重置match
				match = "";
			}
			flag++;
		}
		return model;
	}
}
